﻿using System;
using System.Collections;
using System.Collections.Generic;

namespace Priority_Queue
{
	// Token: 0x0200032F RID: 815
	public sealed class StablePriorityQueue<T> : IFixedSizePriorityQueue<T, float>, IPriorityQueue<T, float>, IEnumerable<T>, IEnumerable where T : StablePriorityQueueNode
	{
		// Token: 0x06001503 RID: 5379 RVA: 0x00089164 File Offset: 0x00087364
		public StablePriorityQueue(int maxNodes)
		{
			this._numNodes = 0;
			this._nodes = new T[maxNodes + 1];
			this._numNodesEverEnqueued = 0L;
		}

		// Token: 0x17000356 RID: 854
		// (get) Token: 0x06001504 RID: 5380 RVA: 0x00089189 File Offset: 0x00087389
		public int Count
		{
			get
			{
				return this._numNodes;
			}
		}

		// Token: 0x17000357 RID: 855
		// (get) Token: 0x06001505 RID: 5381 RVA: 0x00089191 File Offset: 0x00087391
		public int MaxSize
		{
			get
			{
				return this._nodes.Length - 1;
			}
		}

		// Token: 0x06001506 RID: 5382 RVA: 0x0008919D File Offset: 0x0008739D
		public void Clear()
		{
			Array.Clear(this._nodes, 1, this._numNodes);
			this._numNodes = 0;
		}

		// Token: 0x06001507 RID: 5383 RVA: 0x000891B8 File Offset: 0x000873B8
		public bool Contains(T node)
		{
			return this._nodes[node.QueueIndex] == node;
		}

		// Token: 0x06001508 RID: 5384 RVA: 0x000891E0 File Offset: 0x000873E0
		public void Enqueue(T node, float priority)
		{
			node.Priority = priority;
			this._numNodes++;
			this._nodes[this._numNodes] = node;
			node.QueueIndex = this._numNodes;
			long numNodesEverEnqueued;
			this._numNodesEverEnqueued = (numNodesEverEnqueued = this._numNodesEverEnqueued) + 1L;
			node.InsertionIndex = numNodesEverEnqueued;
			this.CascadeUp(this._nodes[this._numNodes]);
		}

		// Token: 0x06001509 RID: 5385 RVA: 0x00089264 File Offset: 0x00087464
		private void Swap(T node1, T node2)
		{
			this._nodes[node1.QueueIndex] = node2;
			this._nodes[node2.QueueIndex] = node1;
			int queueIndex = node1.QueueIndex;
			node1.QueueIndex = node2.QueueIndex;
			node2.QueueIndex = queueIndex;
		}

		// Token: 0x0600150A RID: 5386 RVA: 0x000892DC File Offset: 0x000874DC
		private void CascadeUp(T node)
		{
			for (int i = node.QueueIndex / 2; i >= 1; i = node.QueueIndex / 2)
			{
				T t = this._nodes[i];
				if (this.HasHigherPriority(t, node))
				{
					break;
				}
				this.Swap(node, t);
			}
		}

		// Token: 0x0600150B RID: 5387 RVA: 0x0008933C File Offset: 0x0008753C
		private void CascadeDown(T node)
		{
			int num = node.QueueIndex;
			for (;;)
			{
				T t = node;
				int num2 = 2 * num;
				if (num2 > this._numNodes)
				{
					break;
				}
				T t2 = this._nodes[num2];
				if (this.HasHigherPriority(t2, t))
				{
					t = t2;
				}
				int num3 = num2 + 1;
				if (num3 <= this._numNodes)
				{
					T t3 = this._nodes[num3];
					if (this.HasHigherPriority(t3, t))
					{
						t = t3;
					}
				}
				if (t == node)
				{
					goto IL_D1;
				}
				this._nodes[num] = t;
				int queueIndex = t.QueueIndex;
				t.QueueIndex = num;
				num = queueIndex;
			}
			node.QueueIndex = num;
			this._nodes[num] = node;
			return;
			IL_D1:
			node.QueueIndex = num;
			this._nodes[num] = node;
		}

		// Token: 0x0600150C RID: 5388 RVA: 0x00089440 File Offset: 0x00087640
		private bool HasHigherPriority(T higher, T lower)
		{
			return higher.Priority < lower.Priority || (higher.Priority == lower.Priority && higher.InsertionIndex < lower.InsertionIndex);
		}

		// Token: 0x0600150D RID: 5389 RVA: 0x000894B0 File Offset: 0x000876B0
		public T Dequeue()
		{
			T t = this._nodes[1];
			this.Remove(t);
			return t;
		}

		// Token: 0x0600150E RID: 5390 RVA: 0x000894D4 File Offset: 0x000876D4
		public void Resize(int maxNodes)
		{
			T[] array = new T[maxNodes + 1];
			int num = Math.Min(maxNodes, this._numNodes);
			for (int i = 1; i <= num; i++)
			{
				array[i] = this._nodes[i];
			}
			this._nodes = array;
		}

		// Token: 0x17000358 RID: 856
		// (get) Token: 0x0600150F RID: 5391 RVA: 0x00089523 File Offset: 0x00087723
		public T First
		{
			get
			{
				return this._nodes[1];
			}
		}

		// Token: 0x06001510 RID: 5392 RVA: 0x00089531 File Offset: 0x00087731
		public void UpdatePriority(T node, float priority)
		{
			node.Priority = priority;
			this.OnNodeUpdated(node);
		}

		// Token: 0x06001511 RID: 5393 RVA: 0x00089548 File Offset: 0x00087748
		private void OnNodeUpdated(T node)
		{
			int num = node.QueueIndex / 2;
			T lower = this._nodes[num];
			if (num > 0 && this.HasHigherPriority(node, lower))
			{
				this.CascadeUp(node);
			}
			else
			{
				this.CascadeDown(node);
			}
		}

		// Token: 0x06001512 RID: 5394 RVA: 0x0008959C File Offset: 0x0008779C
		public void Remove(T node)
		{
			if (node.QueueIndex == this._numNodes)
			{
				this._nodes[this._numNodes] = (T)((object)null);
				this._numNodes--;
				return;
			}
			T t = this._nodes[this._numNodes];
			this.Swap(node, t);
			this._nodes[this._numNodes] = (T)((object)null);
			this._numNodes--;
			this.OnNodeUpdated(t);
		}

		// Token: 0x06001513 RID: 5395 RVA: 0x00089630 File Offset: 0x00087830
		public IEnumerator<T> GetEnumerator()
		{
			for (int i = 1; i <= this._numNodes; i++)
			{
				yield return this._nodes[i];
			}
			yield break;
		}

		// Token: 0x06001514 RID: 5396 RVA: 0x0008964B File Offset: 0x0008784B
		IEnumerator IEnumerable.GetEnumerator()
		{
			return this.GetEnumerator();
		}

		// Token: 0x06001515 RID: 5397 RVA: 0x00089654 File Offset: 0x00087854
		public bool IsValidQueue()
		{
			for (int i = 1; i < this._nodes.Length; i++)
			{
				if (this._nodes[i] != null)
				{
					int num = 2 * i;
					if (num < this._nodes.Length && this._nodes[num] != null && this.HasHigherPriority(this._nodes[num], this._nodes[i]))
					{
						return false;
					}
					int num2 = num + 1;
					if (num2 < this._nodes.Length && this._nodes[num2] != null && this.HasHigherPriority(this._nodes[num2], this._nodes[i]))
					{
						return false;
					}
				}
			}
			return true;
		}

		// Token: 0x040017C0 RID: 6080
		private int _numNodes;

		// Token: 0x040017C1 RID: 6081
		private T[] _nodes;

		// Token: 0x040017C2 RID: 6082
		private long _numNodesEverEnqueued;
	}
}
